import { APlugin } from '../types/common.interface';
import { TableDatas } from '../cors/table-datas';
import {  Inject, Injectable, PluginInjectable } from '../decorators/inject';
import { ExecuteRecord } from '../cors/execute-record';
import { NExcel } from '../types';
import { Config } from '../cors/config';
import { createElement } from '../utils/dom-helper';
import { fromEvent } from 'rxjs';
import { filter } from 'rxjs/operators';
import './col-width.plugin.less';
import { EventHelper } from '../utils/event-helper';
import { RenderTrigger } from '../cors/render-trigger';
import { ColWidthCommand } from '../commands/col-width-command';
import { Cache } from '../cors/cache';

@Injectable()
@PluginInjectable('ColHeightPlugin')
export class ColHeightPlugin  extends APlugin{
    protected isEffectHover: boolean = true;
    protected lineEle: HTMLElement;
    protected referenceLine: HTMLElement;
    constructor(
        @Inject(NExcel.OperateContainerToken) protected ele: HTMLElement,
        protected conf: Config,
        protected datas: TableDatas,
        protected executeRecord: ExecuteRecord,
        protected renderTrigger: RenderTrigger,
        protected cache: Cache
    ) {
        super();
    }
    public init() {
        let ele = createElement('div', 'z-table-set-width');
        ele.style.height = this.conf.header.col.height / this.conf.pixelRatio + 'px';
        ele.style.display = 'none';
        let child = createElement('div', 'child');
        // child.style.left = this.conf.header.row.width + 'px';
        child.style.height = String(this.ele.clientHeight - this.conf.header.col.height/this.conf.pixelRatio) + 'px';
        ele.appendChild(child);
        this.lineEle = ele;
        this.referenceLine = child;
        this.ele.appendChild(ele);
        this.showLine();
        this.bindChangeColWidthEvent();
    }
    protected showLine() {
        fromEvent<MouseEvent>(this.ele, 'mousemove')
        .pipe(filter((evt: MouseEvent) => {
            if(this.isEffectHover == false) {
                return false;
            }
            if(evt.offsetX < (this.conf.header.row.width + 1 * this.conf.enlarge)) {
                this.ele.style.cursor = 'default';
                this.lineEle.style.display = 'none';
                return false;
            }
            if(evt.offsetY > this.conf.header.col.height || evt.offsetY < 2) {
                this.ele.style.cursor = 'default';
                this.lineEle.style.display = 'none';
                return false;
            }
            return true;
        }))
        // .pipe(map((evt) => {
        //     // ele.style.top = evt.offsetY + 'px';
        //     // ele.style.left = evt.offsetX + 'px';
        //     return evt;
        // }))
        .subscribe(evt => {
            // let total = this.conf.header.row.width / this.conf.pixelRatio;
            const hoverX =  evt.offsetX * this.conf.pixelRatio;
            let hoverCol = this.cache.getPointCol(hoverX);
            let [_, endX] = this.cache.getColPosition(hoverCol);
            if(hoverX > endX - 3 * this.conf.pixelRatio) {
                let total = endX / this.conf.pixelRatio + 1;
                this.ele.style.cursor = 'col-resize';
                this.lineEle.style.left = total - 2 + 'px';
                this.lineEle.style.display = 'block';
                this.lineEle.style.cursor = 'col-resize';
            } else {
                this.ele.style.cursor = 'default';
                this.lineEle.style.cursor = 'default';
                this.lineEle.style.display = 'none';
            }
        });
    }
    protected bindChangeColWidthEvent() {
        EventHelper.move(
            this.lineEle,
            (evt: MouseEvent) => {
                this.isEffectHover = false;
                this.referenceLine.style.display = 'block';
                let col = this.getClickCol(evt);
                let left = Number(this.lineEle.style.left.replace('px', ''));
                return {x: evt.clientX, y: evt.clientY, col: col, left: left}
            },
            (evt: MouseEvent, param: {x: number, y: number, col: number, left: number}) => {
                let moveX = evt.clientX - param.x;
                let colWidth = (this.datas.getColWidth(param.col) / this.conf.pixelRatio / this.conf.scale) + moveX;
                let setwidth = colWidth > 3 ? colWidth : 3;
                let command  = new ColWidthCommand(this.datas, this.renderTrigger, param.col, setwidth);
                this.executeRecord.execute(command);
                this.isEffectHover = true;
                this.lineEle.style.display = 'none';
                this.referenceLine.style.display = 'none';
            },
            (param: {x: number, y: number, row: number, left: number}, evt: MouseEvent) => {
                let moveX = evt.clientX - param.x;
                this.lineEle.style.left = String(moveX + param.left) + 'px';
                return moveX;
            }
        )
    }
    protected getClickCol(evt: MouseEvent) {
        let left = Number(this.lineEle.style.left.replace('px', '')) * this.conf.pixelRatio - 1;
        let hoverCol = this.cache.getPointCol(left);
        return hoverCol;
    }
    public destroy() {

    }
}